package com.yilin.tms.capital.controller;

import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.DateTimeUtil;
import com.yilin.commons.util.MapUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.capital.commons.strategy.operation.BankOperation;
import com.yilin.tms.capital.commons.strategy.operation.BankOperationFactory;
import com.yilin.tms.capital.service.*;
import com.yilin.tms.core.commons.annotation.NotNull;
import com.yilin.tms.core.commons.annotation.SafeVerify;
import com.yilin.tms.core.commons.annotation.SkipLoginVerify;
import com.yilin.tms.core.commons.annotation.UserTarget;
import com.yilin.tms.core.commons.utils.ParamUtil;
import com.yilin.tms.core.entity.capital.BankCard;
import com.yilin.tms.core.entity.capital.TradeRecord;
import com.yilin.tms.core.entity.order.payment.OrderRefundCost;
import com.yilin.tms.core.entity.order.payment.ServicePaymentCost;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.application.PageData;
import com.yilin.tms.core.application.ReturnData;
import com.yilin.tms.core.commons.base.BaseController;

import com.yilin.tms.core.entity.order.payment.OrderPaymentCost;
import com.yilin.tms.core.entity.order.payment.OrderSettlementCost;
import com.yilin.tms.core.entity.user.UserType;

import com.yilin.tms.core.remote.IOrderRemote;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

/**
 * 支付控制层
 * <p>
 * 支付宝/微信/钱包/代付 等 融合支付
 */
@RestController
@RequestMapping("/capital/trade/")
public class TradeController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(TradeController.class);
    @Resource
    IBankCardService bankCardService;

    @Resource
    IWeCartService weCartService;
    @Resource
    IAlipayService alipayService;
    @Resource
    ITradeRecordService tradeRecordService;

    @Resource
    IOrderRemote orderRemote;

    @Resource
    BankOperationFactory bankOperationFactory;


    /**
     * 获取全部交易记录
     */
    @PostMapping(value = "getTradeRecordPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<TradeRecord>> getTradeRecordPage(TradeRecord query, Integer page, Integer limit) {
        PageData<TradeRecord> tradeRecordPage = tradeRecordService.getTradeRecordPage(query, getLoginUser(), page, limit);
        return jsonView(SUCCESS_CODE, "获取交易分页成功", tradeRecordPage);
    }

    /**
     * 交易记时间段统计
     */
    @PostMapping(value = "getTradeInoutData")
    @NotNull({"startTime", "endTime"})
    public ReturnData<Map<String, Double>> getTradeInoutData(String startTime, String endTime) {
        Date currentDate = new Date();
        if (endTime == null) endTime = DateTimeUtil.dateToString(currentDate, null);
        if (startTime == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(currentDate);
            calendar.add(Calendar.MONTH, -3);
            startTime = DateTimeUtil.dateToString(calendar.getTime(), null);
        }
        Map<String, Double> map = tradeRecordService.getTradeInoutData(getLoginUser(), startTime, endTime);
        return jsonView(SUCCESS_CODE, "获取交易分页成功", map);
    }

    /**
     * 收入交易
     */
    @PostMapping(value = "getIncomeTradeRecordPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<TradeRecord>> getIncomeTradeRecordPage(TradeRecord query, Integer page, Integer limit) {
        PageData<TradeRecord> tradeRecordPage = tradeRecordService.getIncomeTradeRecordPage(query, getLoginUser(), page, limit);
        return jsonView(SUCCESS_CODE, "获取交易分页成功", tradeRecordPage);
    }

    /**
     * 支出交易
     */
    @PostMapping(value = "getPayoutTradeRecordPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<TradeRecord>> getPayoutTradeRecordPage(TradeRecord query, Integer page, Integer limit) {
        PageData<TradeRecord> tradeRecordPage = tradeRecordService.getPayoutTradeRecordPage(query, getLoginUser(), page, limit);
        return jsonView(SUCCESS_CODE, "获取交易分页成功", tradeRecordPage);
    }

    @SkipLoginVerify
    @PostMapping(value = "getTradeRecordListByIds")
    @NotNull({"tradeRecordIds"})
    public ReturnData<List<TradeRecord>> getTradeRecordListByIds(String[] tradeRecordIds) {
        List<TradeRecord> tradeRecordList = tradeRecordService.getTradeRecordListByIds(ArrayUtil.initList(tradeRecordIds));
        return jsonView(SUCCESS_CODE, "获取交易数据成功", tradeRecordList);
    }

    /**
     * 获取平台未生成或生产失败的数据
     */
    @PostMapping(value = "getErrorTmsTradeRecord")
    public ReturnData<List<TradeRecord>> getErrorTmsTradeRecord() {
        List<TradeRecord> tradeRecordList = tradeRecordService.getErrorTmsTradeRecord();
        return jsonView(SUCCESS_CODE, "获取交易分页成功", tradeRecordList);
    }

    @PostMapping(value = "getTradeRecordByNo")
    public ReturnData<TradeRecord> getTradeRecordByNo(String tradeNo) {
        TradeRecord tradeRecord = tradeRecordService.getTradeRecordByTradeNo(tradeNo);
        return jsonView(SUCCESS_CODE, "获取交易分页成功", tradeRecord);
    }

    ///##################################################///支付生产+打包区///###############################################################

    /**
     * 支付：创建支付交易记录 单条
     */
    @PostMapping(value = "createTradeRecord")
    @NotNull({"paymentOrderIds"})
    public ReturnData<TradeRecord> createTradeRecord(String paymentOrderId) {
        OrderPaymentCost payment = ParamUtil.isSuccess(orderRemote.getOrderPaymentById(paymentOrderId));
        if (payment.getPayStatus() != OrderPaymentCost.PayStatus.create) {
            TradeRecord record = tradeRecordService.queryTradeRecordByPaymentId(paymentOrderId);
            if (record != null) return jsonView(SUCCESS_CODE, "已创建过交易记录，已为您返回", record);
        }
        TradeRecord tradeRecord = tradeRecordService.createPaymentTradeRecord(ArrayUtil.initList(payment), getLoginUser());
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecord.getId()));
        return jsonView(SUCCESS_CODE, "创建交易记录成功", tradeRecord);
    }

    /**
     * 支付：创建支付交易记录包
     */
    @PostMapping(value = "createMutTradeRecord")
    @NotNull({"paymentOrderIds"})
    public ReturnData<TradeRecord> createMutTradeRecord(String paymentOrderIds) {
        List<OrderPaymentCost> paymentList = ParamUtil.isSuccess(orderRemote.getOrderPaymentListByIds(paymentOrderIds));
        OrderPaymentCost first = ArrayUtil.first(paymentList);
        for (OrderPaymentCost paymentOrder : paymentList) {
            if (paymentOrder.getPayStatus() != OrderPaymentCost.PayStatus.create) {
                throw new BusinessException(String.format("预付订单(单号：%s)状态不允许交易", paymentOrder.getPrePaymentNo()));
            }
            if (!paymentOrder.getShipperOrganizeId().equals(first.getShipperOrganizeId())) {
                throw new BusinessException("存在支付主体不一致，无法创建交易");
            }
            TradeRecord record = tradeRecordService.queryTradeRecordByPaymentId(paymentOrder.getId());
            if (record != null) {
                throw new BusinessException(String.format("预付订单(单号：%s)已在其他地方发起支付", paymentOrder.getPrePaymentNo()));
            }
        }
        TradeRecord tradeRecord = tradeRecordService.createPaymentTradeRecord(paymentList, getLoginUser());
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecord.getId()));
        return jsonView(SUCCESS_CODE, "创建交易记录成功", tradeRecord);
    }

    /**
     * 结算：创建结算交易记录包
     */
    @PostMapping(value = "createSettlementTradeRecord")
    @NotNull({"settlementOrderIds"})
    public ReturnData<TradeRecord> createSettlementTradeRecord(String settlementOrderIds) {
        List<OrderSettlementCost> settlementList = ParamUtil.isSuccess(orderRemote.getOrderSettlementListByIds(settlementOrderIds));
        OrderSettlementCost first = ArrayUtil.first(settlementList);
        for (OrderSettlementCost settlementCost : settlementList) {
            if (settlementCost.getPayStatus() != OrderSettlementCost.PayStatus.approved) {
                throw new BusinessException(String.format("预付结算单(单号：%s)状态不允许交易", settlementCost.getPrePaymentNo()));
            }
            if (!settlementCost.getTruckerOrganizeId().equals(first.getTruckerOrganizeId())) {
                throw new BusinessException("存在结算主体不一致，无法创建交易");
            }
            /***
             * TODO: 警告
             * 省运管要求按车支付，但是因为存在手续费问题，暂时取消不同车牌号问题
             * 省运管默认只取一个车，造成的问题后续解决
             * */
//            if (!settlementCost.getTruckNo().equals(first.getTruckNo())) {//
//                throw new BusinessException("存在结算主体中不同车牌号，无法创建运管数据，无法创建交易");
//            }
            TradeRecord record = tradeRecordService.queryTradeRecordByPaymentId(settlementCost.getId());
            if (record != null) {
                throw new BusinessException(String.format("预付结算单(单号：%s)已在其他地方发起支付", settlementCost.getPrePaymentNo()));
            }
        }
        TradeRecord tradeRecord = tradeRecordService.createSettlementTradeRecord(settlementList, getLoginUser());
//        ReturnData<OrderPaymentCost> returnData = orderRemote.generateServicePayment(tradeRecord.getId());
//        if (!returnData.isSuccess()){
//            tradeRecord.setTradeStatus(TradeRecord.TradeStatus.payFail);
//            tradeRecordService.removeById(tradeRecord);
//            return jsonView(FAIL_CODE, "创建交易记录时生成费用单失败，交易记录已取消", tradeRecord);
//        }
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecord.getId()));
        return jsonView(SUCCESS_CODE, "创建交易记录成功", tradeRecord);
    }

//    /**
//     * 结算：创建结算交易记录包
//     */
//    @PostMapping(value = "createSettlementTradeRecord")
//    @NotNull({"settlementOrderIds"})
//    public ReturnData<Map<String,TradeRecord>> createSettlementTradeRecord(String settlementOrderIds) {
//        List<OrderSettlementCost> allSettlementList = ParamUtil.isSuccess(orderRemote.getOrderSettlementListByIds(settlementOrderIds));
//        Map<String,List<OrderSettlementCost>> orderSettlementCostMap = new HashMap<>();
//        for (OrderSettlementCost settlementCost : allSettlementList) {
//            if (settlementCost.getPayStatus() != OrderSettlementCost.PayStatus.approved) {
//                throw new BusinessException(String.format("预付结算单(单号：%s)状态不允许交易", settlementCost.getPrePaymentNo()));
//            }
//            if (tradeRecordService.queryTradeRecordByPaymentId(settlementCost.getId()) != null) {
//                throw new BusinessException(String.format("预付结算单(单号：%s)已在其他地方发起支付", settlementCost.getPrePaymentNo()));
//            }
//            orderSettlementCostMap.putIfAbsent(settlementCost.getTruckNo(),new ArrayList<>());
//            orderSettlementCostMap.get(settlementCost.getTruckNo()).add(settlementCost);
//        }
//        Map<String,TradeRecord> tradeRecordMap = new HashMap<>();
//        for (String truckNo : orderSettlementCostMap.keySet()) {
//            List<OrderSettlementCost> settlementCostList = orderSettlementCostMap.get(truckNo);
//            OrderSettlementCost first = ArrayUtil.first(settlementCostList);
//            for (OrderSettlementCost settlementCost : settlementCostList) {
//                if (!settlementCost.getTruckerOrganizeId().equals(first.getTruckerOrganizeId())) {
//                    throw new BusinessException("存在结算主体不一致，无法创建交易,(请检查同一车牌号是否被多个车队使用！)");
//                }
//            }
//            TradeRecord tradeRecord = tradeRecordService.createSettlementTradeRecord(settlementCostList, getLoginUser());
//            ReturnData<OrderPaymentCost> returnData = orderRemote.generateServicePayment(tradeRecord.getId());
//            if (!returnData.isSuccess()){
//                tradeRecord.setTradeStatus(TradeRecord.TradeStatus.payFail);
//                tradeRecordService.removeById(tradeRecord);
//                throw new BusinessException("存在结算主体不一致，无法创建交易,(请检查同一车牌号是否被多个车队使用！)");
//            }
//            //通知支付结果
//            tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecord.getId()));
//        }
//        return jsonView(SUCCESS_CODE, "创建交易记录成功", tradeRecordMap);
//    }

    /**
     * 结算：创建服务费交易记录包
     */
    @PostMapping(value = "createServicePaymentTradeRecord")
    @NotNull({"servicePaymentIds"})
    public ReturnData<TradeRecord> createServicePaymentTradeRecord(String servicePaymentIds) {
        List<ServicePaymentCost> servicePaymentList = ParamUtil.isSuccess(orderRemote.getServicePaymentListByIds(servicePaymentIds));
        ServicePaymentCost first = ArrayUtil.first(servicePaymentList);
        for (ServicePaymentCost servicePayment : servicePaymentList) {
            if (servicePayment.getPayStatus() != ServicePaymentCost.PayStatus.approved) {
                throw new BusinessException(String.format("预付结算单(单号：%s)状态不允许交易", servicePayment.getPrePaymentNo()));
            }
            if (!servicePayment.getSuperiorPlatId().equals(first.getSuperiorPlatId())) {
                throw new BusinessException("存在收款主体不一致，无法创建交易");
            }
            TradeRecord record = tradeRecordService.queryTradeRecordByPaymentId(servicePayment.getId());
            if (record != null) {
                throw new BusinessException(String.format("预付结算单(单号：%s)已在其他地方发起支付", servicePayment.getPrePaymentNo()));
            }
        }
        TradeRecord tradeRecord = tradeRecordService.createServicePaymentTradeRecord(servicePaymentList, getLoginUser());
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecord.getId()));
        return jsonView(SUCCESS_CODE, "创建交易记录成功", tradeRecord);
    }

    /**
     * 退款：创建退款交易记录包
     */
    @PostMapping(value = "createRefundTradeRecord")
    @NotNull({"refundOrderId"})
    public ReturnData<TradeRecord> createRefundTradeRecord(String refundOrderId) {
        OrderRefundCost orderRefundCost = ParamUtil.isSuccess(orderRemote.getOrderRefundById(refundOrderId));
        if (StringUtil.isEmpty(orderRefundCost.getVerifyUserId())) return jsonErrView("交易未锁定");
        if (!orderRefundCost.getVerifyUserId().equals(getLoginUser().getId())) return jsonErrView("此交易已被他人操作");
        TradeRecord tradeRecord = tradeRecordService.createRefundTradeRecord(orderRefundCost, getLoginUser());
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecord.getId()));
        return jsonView(SUCCESS_CODE, "创建交易记录成功", tradeRecord);
    }

    /**
     * 关闭交易记录
     */
    @PostMapping(value = "closeTradeRecord")
    @NotNull({"tradeRecordId"})
    public ReturnData<TradeRecord> closeTradeRecord(String tradeRecordId) {
        TradeRecord tradeRecord = tradeRecordService.getTradeRecordById(tradeRecordId);
        if (tradeRecord.getTradeStatus() == TradeRecord.TradeStatus.paySuccess) {
            return jsonErrView("交易已成功，无法关闭！");
        }
        if (tradeRecord.getTradeStatus() == TradeRecord.TradeStatus.wait) {
            return jsonErrView("交易正在处理，请稍后再试！");
        }
        if (tradeRecord.getTradeStatus() == TradeRecord.TradeStatus.doubt) {
            return jsonErrView("交易正在处理，请稍后！");
        }
        tradeRecord.setTradeStatus(TradeRecord.TradeStatus.close);
        tradeRecordService.updateById(tradeRecord);
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecordId));
        return jsonView(SUCCESS_CODE, "获取交易记录成功", tradeRecord);
    }

    /**
     * 锁定交易记录
     */
    @PostMapping(value = "lockTradeRecord")
    @NotNull({"tradeRecordIds"})
    @SafeVerify
    public ReturnData<TradeRecord> lockTradeRecord(String[] tradeRecordIds, Boolean optLock) {
        if (optLock == null) optLock = false;
        List<TradeRecord> tradeRecordList = tradeRecordService.getTradeRecordListByIds(ArrayUtil.initList(tradeRecordIds));
        for (TradeRecord tradeRecord : tradeRecordList) {
            if (tradeRecord.getOptLock() && !tradeRecord.getOptUserId().equals(getLoginUser().getId())) {
                return jsonErrView("该记录已被锁定");
            }
            tradeRecord.setOptLock(optLock);
            tradeRecord.setOptUserId(optLock ? getLoginUser().getId() : null);
            tradeRecord.setOptUserName(optLock ? getLoginUser().getName() : null);
            tradeRecord.setOptLockTime(optLock ? new Date() : null);
        }
        tradeRecordService.updateBatchById(tradeRecordList);
        return jsonView(SUCCESS_CODE, "记录" + (optLock ? "锁定" : "解锁") + "成功");
    }

    /**
     * 核对交易记录
     */
    @PostMapping(value = "checkTradeRecord")
    @NotNull({"tradeRecordIds"})
    public ReturnData<TradeRecord> checkTradeRecord(String[] tradeRecordIds, Boolean reconciliation) {
        if (reconciliation == null) reconciliation = false;
        List<TradeRecord> tradeRecordList = tradeRecordService.getTradeRecordListByIds(ArrayUtil.initList(tradeRecordIds));
        for (TradeRecord tradeRecord : tradeRecordList) {
            tradeRecord.setReconciliation(reconciliation);
        }
        tradeRecordService.updateBatchById(tradeRecordList);
        return jsonView(SUCCESS_CODE, "记录核对" + (reconciliation ? "成功" : "失败"));
    }

    /**
     * 获取账户支持的交易方式
     */
    @PostMapping(value = "getAllTradeTypeList")
    @UserTarget()
    public ReturnData<Object> getAllTradeTypeList() {
        List<Map<String, Object>> tradeList = new ArrayList<>();
        // ### 添加微信支付
        tradeList.add(MapUtil.generate(map -> {
            map.put("label", "微信支付");
            map.put("payType", TradeRecord.PayType.wxPay);
            map.put("icon", "xbr_weixinpay");
        }));
        // ### 添加支付宝支付
        tradeList.add(MapUtil.generate(map -> {
            map.put("label", "支付宝支付");
            map.put("payType", TradeRecord.PayType.alipay);
            map.put("icon", "xbr_alipay");
        }));
        // ### 线下转账
        tradeList.add(MapUtil.generate(map -> {
            map.put("label", "对公转账");
            map.put("tip", " (线下汇款)");
            map.put("payType", TradeRecord.PayType.bankPay);
            map.put("icon", "xbr_zhuanzhang");
            map.put("data", new HashMap<>());//平台收款账号信息
        }));
        return jsonView(true, "获取所有交易方式成功", tradeList);
    }

    ///##################################################///支付操作区///###############################################################

    /**
     * 支付操作 1 : 货主支付
     * 微信支付，订单生成 返回到APP支付  发起
     */
    @PostMapping(value = "generateWeixinPayOrder")
    public ReturnData<Object> generateWeixinPayOrder(String tradeRecordId) {
        ParamUtil.isNull(tradeRecordId, "请传入支付单信息");
        Account account = getLoginUser();
        TradeRecord tradeRecord = tradeRecordService.getTradeRecordById(tradeRecordId);
        ParamUtil.isNull(tradeRecord, "获取支付单失败");
        Object object = null;
        if (account.getTerminalType() == Account.TerminalType.android || account.getTerminalType() == Account.TerminalType.ios) {
            object = weCartService.wxChartAppTransactions(account, tradeRecord, "app");
        } else if (account.getTerminalType() == Account.TerminalType.web) {
            object = weCartService.wxChartAppTransactions(account, tradeRecord, "web");
        }
        return jsonView(true, "微信支付下单成功", object);
    }

    /**
     * 支付操作 2 : 货主支付
     * 支付包支付，订单生成 返回到APP支付  发起
     */
    @PostMapping(value = "generateAlipayOrder")
    public ReturnData<Object> generateAlipayOrder(String tradeRecordId, String requestFromURl) {
        ParamUtil.isNull(tradeRecordId, "请传入支付单信息");
        Account account = getLoginUser();
        TradeRecord tradeRecord = tradeRecordService.getTradeRecordById(tradeRecordId);
        ParamUtil.isNull(tradeRecord, "获取支付单失败");
        Object object = null;
        if (account.getTerminalType() == Account.TerminalType.android || account.getTerminalType() == Account.TerminalType.ios) {
            object = alipayService.tradePaymentOrder(account, tradeRecord, "app", null);
        } else if (account.getTerminalType() == Account.TerminalType.web) {
            object = alipayService.tradePaymentOrder(account, tradeRecord, "web", requestFromURl);
        }
        return jsonView(true, "支付宝支付下单成功", object);
    }

    /**
     * 支付操作 3 : 货主支付
     * 支付包支付，订单生成 對公汇款 发起
     */
    @PostMapping(value = "offlineTransferMoney")
    public ReturnData<TradeRecord> offlineTransferMoney(String tradeRecordId) {
        TradeRecord tradeRecord = tradeRecordService.getTradeRecordById(tradeRecordId);
        if (tradeRecord.getTradeStatus() != TradeRecord.TradeStatus.create) {
            return jsonErrView("交易(" + tradeRecord.getTradeNo() + ")状态不再待支付状态");
        }
        tradeRecord.setOptLock(true);
        tradeRecord.setOptUserId(getLoginUser().getId());
        tradeRecord.setOptUserName(getLoginUser().getName());
        tradeRecord.setOptLockTime(new Date());
        tradeRecord.setTradeStatus(TradeRecord.TradeStatus.wait);
        tradeRecord.setBankType(TradeRecord.BankType.none);
        tradeRecord.setPayType(TradeRecord.PayType.bankPay);
        tradeRecord.setInitiateTime(new Date());
        tradeRecordService.updateById(tradeRecord);
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(tradeRecordId));
        return jsonView(true, "货主支付已发起，请尽快完成支付");
    }

    /**
     * 支付操作 4 : 平台支付
     * 银行直连，直接发起交易
     */
    @PostMapping(value = "bankTransferPay")
    public ReturnData<TradeRecord> bankTransferPay(String[] tradeRecordIds, TradeRecord.BankType bankType, String payBankCardId) {
        List<TradeRecord> tradeRecordList = tradeRecordService.getTradeRecordListByIds(ArrayUtil.initList(tradeRecordIds));
        //获取付款卡，用此卡支付选中的记录
        BankCard payBankCard = bankCardService.getBackCardById(payBankCardId);
        for (TradeRecord tradeRecord : tradeRecordList) {
            if (!tradeRecord.getOptLock()) return jsonErrView("交易未锁定");
            if (!tradeRecord.getOptUserId().equals(getLoginUser().getId())) return jsonErrView("此交易已被他人操作");
            //待支付和失败
            List<TradeRecord.TradeStatus> statusList = ArrayUtil.initList(TradeRecord.TradeStatus.create, TradeRecord.TradeStatus.payFail);
            if (!statusList.contains(tradeRecord.getTradeStatus())) {
                return jsonErrView("交易(" + tradeRecord.getTradeNo() + ")状态不再待支付状态");
            }
            tradeRecord.setPayType(TradeRecord.PayType.bankPay);
            tradeRecord.setBankType(bankType);
            tradeRecord.setPaymentBackCard(payBankCard);
            tradeRecord.setPaymentCapitalAccount(payBankCard.getBankAccNo());
            //获取收款人默认银行卡
            BankCard incBankCard = bankCardService.getDefaultBankCardByOrganizeId(tradeRecord.getIncomeOrganizeId());
            tradeRecord.setIncomeCapitalAccount(incBankCard.getBankAccNo());
            tradeRecord.setCollectionBackCard(incBankCard);
        }
        /*BankOperationFactory.java 添加对应的银行判断*/
        BankOperation bankOperation = bankOperationFactory.createBankOperation(bankType, TradeRecord.PayType.bankPay);
        bankOperation.execute(tradeRecordList, getLoginUser());
        //通知支付结果
        tradeRecordService.noticePaymentResult(tradeRecordIds);
        return jsonView(SUCCESS_CODE, "交易已发起，请等待银行结果", null);
    }

    /**
     * 支付操作 5 : 特殊 手动操作
     * 用于平台主动设置交易方式和交易结果
     * 线下支付 手动操控结果
     */
    @SafeVerify()
    @PostMapping(value = "handDealPayResult")
    @UserTarget({UserType.adminUser, UserType.yilinUser, UserType.zoneUser, UserType.platformUser})
    @NotNull({"paymentCapitalAccount", "bankFlowNo", "finishTime"})
    public ReturnData<Object> handDealPayResult(TradeRecord tradeRecord) {
        TradeRecord localRecord = tradeRecordService.getTradeRecordById(tradeRecord.getId());
        if (tradeRecord.getTradeStatus() == TradeRecord.TradeStatus.paySuccess) {
            return jsonErrView("交易已成功，无法更新！");
        }
        if (tradeRecord.getFinishTime().after(new Date())) {
            return jsonErrView("交易时间不能大于当前时间！");
        }
        tradeRecord.setOptLock(true);
        tradeRecord.setOptUserId(getLoginUser().getId());
        tradeRecord.setOptUserName(getLoginUser().getName());
        tradeRecord.setOptLockTime(new Date());
        localRecord.setTradeStatus(TradeRecord.TradeStatus.paySuccess);
        localRecord.setPayType(TradeRecord.PayType.bankPay);
        localRecord.setBankType(TradeRecord.BankType.none);
        localRecord.setPaymentCapitalAccount(tradeRecord.getPaymentCapitalAccount());
        localRecord.setBankFlowNo(tradeRecord.getBankFlowNo());
        localRecord.setFinishTime(tradeRecord.getFinishTime());
        tradeRecordService.updateById(localRecord);
        //通知支付结果
        tradeRecordService.noticePaymentResult(ArrayUtil.initArr(localRecord.getId()));
        return jsonView(true, "手动操作成功");
    }

    /**
     * 发起退款
     */
    @PostMapping(value = "initiateTradeRecordRefund")
    @NotNull({"tradeRecordId"})
    @SafeVerify
    public ReturnData<Object> initiateTradeRecordRefund(String tradeRecordId) {
        TradeRecord localRecord = tradeRecordService.getTradeRecordById(tradeRecordId);
        /*BankOperationFactory.java 添加对应的银行判断*/
        if (localRecord.getPayType() == TradeRecord.PayType.bankPay) {//银行支付
            BankCard payBankCard = bankCardService.getBackCardByNo(localRecord.getPaymentCapitalAccount());
            localRecord.setPaymentBackCard(payBankCard);
            BankCard incBankCard = bankCardService.getBackCardByNo(localRecord.getIncomeCapitalAccount());
            localRecord.setCollectionBackCard(incBankCard);
        }
        /*BankOperationFactory.java 添加对应的银行判断*/
        BankOperation bankOperation = bankOperationFactory.createBankOperation(localRecord.getBankType(), localRecord.getPayType());
        localRecord = bankOperation.executeRefund(localRecord, getLoginUser());
        return jsonView(true, "退款发起成功", localRecord);
    }


    //################################################交易结果查询########################################################################

    /**
     * 交易结果查询
     */
    @PostMapping(value = "getTradeRecordStatusById")
    @NotNull({"tradeRecordId"})
    public ReturnData<Object> getTradeRecordStatusById(String tradeRecordId) {
        TradeRecord localRecord = tradeRecordService.getTradeRecordById(tradeRecordId);
        if (localRecord.getTradeStatus() == TradeRecord.TradeStatus.paySuccess) {
            return jsonView(true, "查询成功", localRecord);
        }
        /*BankOperationFactory.java 添加对应的银行判断*/
        BankOperation bankOperation = bankOperationFactory.createBankOperation(localRecord.getBankType(), localRecord.getPayType());
        localRecord = bankOperation.executeQuery(localRecord, getLoginUser());
        return jsonView(true, "查询成功", localRecord);
    }


}
